0%

HarekazeCTF2019 encode_and_encode

[HarekazeCTF2019]encode_and_encode

感觉是一个外国比赛的签到题,思路很清楚就是不知道怎么实现
题目给了源码

<?php
error_reporting(0);

if (isset($_GET['source'])) {
  show_source(__FILE__);
  exit();
}

function is_valid($str) {
  $banword = [
    // no path traversal
    '\.\.',
    // no stream wrapper
    '(php|file|glob|data|tp|zip|zlib|phar):',
    // no data exfiltration
    'flag'
  ];
  $regexp = '/' . implode('|', $banword) . '/i';
  if (preg_match($regexp, $str)) {
    return false;
  }
  return true;
}

$body = file_get_contents('php://input');
$json = json_decode($body, true);

if (is_valid($body) && isset($json) && isset($json['page'])) 
{
  $page = $json['page'];
  $content = file_get_contents($page);
  if (!$content || !is_valid($content)) 
  {
    $content = "<p>not found</p>\n";
  }
} 
else 
{
  $content = '<p>invalid request</p>';
}

// no data exfiltration!!!
$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{&lt;censored&gt;}', $content);
echo json_encode(['content' => $content]);

获取我们的输入用json方式解码,解码前需要将输入内容进行一个过滤,然后再把file_get_contents的内容在进行一次过滤,两次均通过判断即可输出,输出之前再把flag给你替换掉

题解

思路很简单,file_get_contents支持php://filter,只要用这个伪协议读取文件,将其base64编码即可绕过对内容的过滤和替换,但是问题在于输入也需要一层过滤,且不能出现php字样
这里则是利用json解码时支持Unicode编码的,用Unicode替换掉一两个关键字就可以了
p=\u0070 f=\u0066